#pragma once

#define VOID_VER "0.0.1"

#include <assert.h>
#include <type_traits>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <streambuf>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <algorithm>
#include <functional>
using namespace std;

#ifndef VOID_NS1
#define VOID_NS1(a_Name) namespace a_Name {
#define VOID_NS0(a_Name) }
#endif

#include "Ary.h"
#include "Tup.h"
#include "Fun.h"
#include "Class.h" // 用户类扩展

VOID_NS1(nVoid)

/// 解析JSON，结果可能是 null，bool，int，float，tStr，tDic，tTup
/// 当失败时，a_Errs包含错误消息，a_Rst为i_Null；成功时a_Errs为空，a_Rst是解析结果
inline bool fParseJson(tStr& a_Errs, tVar& a_Rst, tStr a_Json);
inline bool fParseJsonFromFile(tStr& a_Errs, tVar& a_Rst, tStr a_Path);


//=============================================================【下面都是没有写入类里的实现代码】

tStr atVal::cRealTypename() const
{
	return (this->i_Type == tType::i_itClass) ? this->cTypedValAt<itClass>()->vdVoid_RealTypename() : tStr();
}

atVal::operator bool() const
{
	switch (this->i_Type)
	{
	case tType::i_null: return false;
	case tType::i_bool: return (*this->cTypedValAt<bool>());
	case tType::i_int: return (bool)(*this->cTypedValAt<long long>());
	case tType::i_uint: return (bool)(*this->cTypedValAt<unsigned long long>());
	case tType::i_float: return (bool)(*this->cTypedValAt<double>());
	case tType::i_tStr: return (bool)(*this->cTypedValAt<tStr>());
	case tType::i_tDic: return (bool)(*this->cTypedValAt<tDic>());
	case tType::i_tTup: return (bool)(*this->cTypedValAt<tTup>());
//	case tType::i_tFun: return true;
	case tType::i_itClass: return this->cTypedValAt<itClass>()->vdVoid_ToBool();
	}
	return false;
}

atVal::operator long long() const
{
	switch (this->i_Type)
	{
	case tType::i_null: return 0;
	case tType::i_bool: return (long long)(*this->cTypedValAt<bool>());
	case tType::i_int: return (*this->cTypedValAt<long long>());
	case tType::i_uint: return (long long)(*this->cTypedValAt<unsigned long long>());
	case tType::i_float: return (long long)(*this->cTypedValAt<double>());
	case tType::i_tStr: return std::stoll(*this->cTypedValAt<tStr>());
	case tType::i_tDic: return this->cTypedValAt<tDic>()->cLen();
	case tType::i_tTup: return this->cTypedValAt<tTup>()->cLen();
	case tType::i_itClass: return this->cTypedValAt<itClass>()->vdVoid_ToLongLong();
	}
	return 0;
}

atVal::operator unsigned long long() const
{
	switch (this->i_Type)
	{
	case tType::i_null: return 0;
	case tType::i_bool: return (unsigned long long)(*this->cTypedValAt<bool>());
	case tType::i_int: return (unsigned long long)(*this->cTypedValAt<long long>());
	case tType::i_uint: return (*this->cTypedValAt<unsigned long long>());
	case tType::i_float: return (long long)(*this->cTypedValAt<double>());
	case tType::i_tStr: return std::stoull(*this->cTypedValAt<tStr>());
	case tType::i_tDic: return this->cTypedValAt<tDic>()->cLen();
	case tType::i_tTup: return this->cTypedValAt<tTup>()->cLen();
	case tType::i_itClass: return this->cTypedValAt<itClass>()->vdVoid_ToUnsignedLongLong();
	}
	return 0;
}

atVal::operator double() const
{
	switch (this->i_Type)
	{
	case tType::i_null: return 0.0;
	case tType::i_bool: return (double)(*this->cTypedValAt<bool>());
	case tType::i_int: return (double)(*this->cTypedValAt<long long>());
	case tType::i_uint: return (double)(*this->cTypedValAt<unsigned long long>());
	case tType::i_float: return (*this->cTypedValAt<double>());
	case tType::i_tStr: return std::stod(*this->cTypedValAt<tStr>());
	case tType::i_tDic: return (double)(this->cTypedValAt<tDic>()->cLen());
	case tType::i_tTup: return (double)(this->cTypedValAt<tTup>()->cLen());
	case tType::i_itClass: return this->cTypedValAt<itClass>()->vdVoid_ToDouble();
	}
	return 0;
}

atVal::operator tTup const& () const
{
	if (this->i_Type != tType::i_tTup) { throw exception(tStr::scCat("Type Error: Can not cast <", this->cTypename(), "> to <tTup>.")); }
	return *this->cTypedValAt<tTup>();
}

atVal::operator tDic const& () const
{
	if (this->i_Type != tType::i_tDic) { throw exception(tStr::scCat("Type Error: Can not cast <", this->cTypename(), "> to <tDic>.")); }
	return *this->cTypedValAt<tDic>();
}

atVal::operator tFun const& () const
{
	if (this->i_Type != tType::i_tFun) { throw exception(tStr::scCat("Type Error: Can not cast <", this->cTypename(), "> to <tFun>.")); }
	return *this->cTypedValAt<tFun>();
}

atVal::operator ptClass() const
{
	if (this->i_Type != tType::i_itClass) { throw exception(tStr::scCat("Type Error: Can not cast <", this->cTypename(), "> to <itClass>.")); }
	return *this->cTypedValAt<ptClass>();
}

ptVal tValidVal<tFun>::vdCopy() const 
{ 
	return ptVal(new tVal<tFun>(this->c_Val)); 
}

ptVal tValidVal<itClass>::vdCopy() const 
{ 
	return ptVal(new tVal<itClass>(this->c_Val->vdVoid_Copy(this->c_Val)));
}

bool operator ==(atVal const& a_LHS, atVal const& a_RHS)
{
	if (a_LHS.i_Type == tType::i_itClass) { return (*a_LHS.operator ptClass()).vdVoid_Cmp("==", a_RHS); }
	if (a_RHS.i_Type == tType::i_itClass) { return (*a_RHS.operator ptClass()).vdVoid_Cmp("==", a_LHS); }

	if (a_LHS.i_Type == tType::i_null && a_RHS.i_Type == tType::i_null) { return true; }
	if (a_LHS.i_Type == tType::i_null || a_RHS.i_Type == tType::i_null) { return false; }

	if (a_LHS.i_Type == tType::i_bool || a_RHS.i_Type == tType::i_bool) { return (bool)a_LHS == (bool)a_RHS; }

	if (a_LHS.i_Type == tType::i_int)
	{
		auto o_L = *a_LHS.cTypedValAt<long long>();
		if (a_RHS.i_Type == tType::i_int) { return o_L == *a_RHS.cTypedValAt<long long>(); }
		if (a_RHS.i_Type == tType::i_uint) { return o_L == (long long)*a_RHS.cTypedValAt<unsigned long long>(); }
		if (a_RHS.i_Type == tType::i_float) { return (double)o_L == *a_RHS.cTypedValAt<double>(); }
		return false;
	}
	if (a_LHS.i_Type == tType::i_uint)
	{
		auto o_L = *a_LHS.cTypedValAt<unsigned long long>();
		if (a_RHS.i_Type == tType::i_int) { return (long long)o_L == *a_RHS.cTypedValAt<long long>(); }
		if (a_RHS.i_Type == tType::i_uint) { return o_L == *a_RHS.cTypedValAt<unsigned long long>(); }
		if (a_RHS.i_Type == tType::i_float) { return (double)o_L == *a_RHS.cTypedValAt<double>(); }
		return false;
	}
	if (a_LHS.i_Type == tType::i_float)
	{
		auto o_L = *a_LHS.cTypedValAt<double>();
		if (a_RHS.i_Type == tType::i_int) { return o_L == (double)*a_RHS.cTypedValAt<long long>(); }
		if (a_RHS.i_Type == tType::i_uint) { return o_L == (double)*a_RHS.cTypedValAt<unsigned long long>(); }
		if (a_RHS.i_Type == tType::i_float) { return o_L == *a_RHS.cTypedValAt<double>(); }
		return false;
	}

	if (a_LHS.i_Type != a_RHS.i_Type) { return false; }
	if (a_LHS.i_Type == tType::i_tStr) { return *a_LHS.cTypedValAt<tStr>() == *a_RHS.cTypedValAt<tStr>(); }
	if (a_LHS.i_Type == tType::i_tDic) { return *a_LHS.cTypedValAt<tDic>() == *a_RHS.cTypedValAt<tDic>(); }
	if (a_LHS.i_Type == tType::i_tTup) { return *a_LHS.cTypedValAt<tTup>() == *a_RHS.cTypedValAt<tTup>(); }

	return a_LHS.c_pValAt == a_RHS.c_pValAt; // tFun
}

bool operator <(atVal const& a_LHS, atVal const& a_RHS)
{
	if (a_LHS.i_Type == tType::i_itClass) { return (*a_LHS.operator ptClass()).vdVoid_Cmp("<", a_RHS); }
	if (a_RHS.i_Type == tType::i_itClass) { return (*a_RHS.operator ptClass()).vdVoid_Cmp(">", a_LHS); }

	if (a_LHS.i_Type == tType::i_null || a_RHS.i_Type == tType::i_null) { return false; }

	if (a_LHS.i_Type == tType::i_bool)
	{
		auto o_L = *a_LHS.cTypedValAt<bool>();
		if (a_RHS.i_Type == tType::i_bool) { return (long long)o_L < (long long)*a_RHS.cTypedValAt<bool>(); }
		if (a_RHS.i_Type == tType::i_int) { return (long long)o_L < *a_RHS.cTypedValAt<long long>(); }
		if (a_RHS.i_Type == tType::i_uint) { return (unsigned long long)o_L < *a_RHS.cTypedValAt<unsigned long long>(); }
		if (a_RHS.i_Type == tType::i_float) { return (double)o_L < *a_RHS.cTypedValAt<double>(); }
		return false;
	}
	if (a_LHS.i_Type == tType::i_int)
	{
		auto o_L = *a_LHS.cTypedValAt<long long>();
		if (a_RHS.i_Type == tType::i_bool) { return o_L < (long long)*a_RHS.cTypedValAt<bool>(); }
		if (a_RHS.i_Type == tType::i_int) { return o_L < *a_RHS.cTypedValAt<long long>(); }
		if (a_RHS.i_Type == tType::i_uint) { return (o_L < 0) || ((unsigned long long)o_L < *a_RHS.cTypedValAt<unsigned long long>()); } //【注意】
		if (a_RHS.i_Type == tType::i_float) { return (double)o_L < *a_RHS.cTypedValAt<double>(); }
		return false;
	}
	if (a_LHS.i_Type == tType::i_uint)
	{
		auto o_L = *a_LHS.cTypedValAt<unsigned long long>();
		if (a_RHS.i_Type == tType::i_bool) { return o_L < (unsigned long long)*a_RHS.cTypedValAt<bool>(); }
		if (a_RHS.i_Type == tType::i_int) { auto o_R = *a_RHS.cTypedValAt<long long>(); return (o_R >= 0) && (o_L < (unsigned long long)o_R); } //【注意】
		if (a_RHS.i_Type == tType::i_uint) { return o_L < *a_RHS.cTypedValAt<unsigned long long>(); }
		if (a_RHS.i_Type == tType::i_float) { return (double)o_L < *a_RHS.cTypedValAt<double>(); }
		return false;
	}
	if (a_LHS.i_Type == tType::i_float)
	{
		auto o_L = *a_LHS.cTypedValAt<double>();
		if (a_RHS.i_Type == tType::i_bool) { return o_L < (double)*a_RHS.cTypedValAt<bool>(); }
		if (a_RHS.i_Type == tType::i_int) { return o_L < (double)*a_RHS.cTypedValAt<long long>(); }
		if (a_RHS.i_Type == tType::i_uint) { return o_L < (double)*a_RHS.cTypedValAt<unsigned long long>(); }
		if (a_RHS.i_Type == tType::i_float) { return o_L < *a_RHS.cTypedValAt<double>(); }
		return false;
	}

	if (a_LHS.i_Type != a_RHS.i_Type) { return false; }
	if (a_LHS.i_Type == tType::i_tStr) { return *a_LHS.cTypedValAt<tStr>() < *a_RHS.cTypedValAt<tStr>(); }
	
	return false;
}

template<class a_tWhich>
tVar tRefVar<a_tWhich>::cCall(tStr const& a_M)
{
	if (this->cType() != tType::i_itClass) { throw exception(tStr::scCat("Type Error: Only <itClass> supports \"cCall()\".")); }

	tTup o_Args;
	return this->eThis()->cVal().cTypedValAt<itClass>()->vdVoid_Call(a_M, o_Args);
}

template<class a_tWhich>
template<class a_tArg, class... a_tArgs>
tVar tRefVar<a_tWhich>::cCall(tStr const& a_M, a_tArg const& a_Arg, a_tArgs... a_Args)
{
	if (this->cType() != tType::i_itClass) { throw exception(tStr::scCat("Type Error: Only <itClass> supports \"cCall()\".")); }

	tTup o_Args;
	tTup::scAdd(o_Args, a_Arg, a_Args...);
	return this->eThis()->cVal().cTypedValAt<itClass>()->vdVoid_Call(a_M, o_Args);
}

template<class a_tWhich>
template<class a_tClass>
a_tClass& tRefVar<a_tWhich>::cInst()
{
	if (this->cType() != tType::i_itClass) { throw exception(tStr::scCat("Type Error: Only <itClass> supports \"cProp()\".")); }

	return *dynamic_cast<a_tClass*>(this->eThis()->cVal().cTypedValAt<itClass>());
}

template<class a_tWhich>
template<class a_tClass>
a_tClass const& tRefVar<a_tWhich>::cInst() const
{
	if (this->cType() != tType::i_itClass) { throw exception(tStr::scCat("Type Error: Only <itClass> supports \"cProp()\".")); }

	return *dynamic_cast<a_tClass const*>(this->eThis()->cVal().cTypedValAt<itClass>());
}

tVar tRef::operator ()()
{
	tType i_Type = this->cType();
	if (i_Type == tType::i_tFun)
	{
		return this->operator ()(tDic());
	}
	else if (i_Type == tType::i_itClass)
	{
		return this->cCall("()");
	}

	throw exception(tStr::scCat("Type Error: Only <tRef -> tDic[tFun]> and <itClass> support \"()\"."));
}

tVar tRef::operator ()(tDic const& a_Args)
{
	tType i_Type = this->cType();
	if (i_Type == tType::i_tFun)
	{
		if (!this->c_pDic) { throw exception("Call Error: <tRef> must originate from <tDic>."); }
		tFun& o_fFun = *this->cVal().cTypedValAt<tFun>();
		tDic o_ArgsDic(a_Args); o_fFun.cMakeArgsDic(o_ArgsDic);
		return o_fFun.operator()(*this->c_pDic, o_ArgsDic);
	}
	else if (i_Type == tType::i_itClass)
	{
		return this->cCall("()", a_Args);
	}

	throw exception(tStr::scCat("Type Error: Only <tRef -> tDic[tFun]> and <itClass> support \"()\"."));
}

template<class a_tArg, class... a_tArgs>
tVar tRef::operator ()(tKV<a_tArg> const& a_Arg, a_tArgs... a_Args)
{
	tDic o_ArgsDic;
	tDic::scAdd(o_ArgsDic, a_Arg, a_Args...);
	return this->operator ()(o_ArgsDic);
}

template<class a_tArg, class... a_tArgs>
tVar tRef::operator ()(a_tArg const& a_Arg, a_tArgs... a_Args)
{
	tType i_Type = this->cType();
	if (i_Type == tType::i_tFun)
	{
		if (!this->c_pDic) { throw exception("Call Error: <tRef> must originate from <tDic>."); }
		tFun& o_fFun = *this->cVal().cTypedValAt<tFun>();
		tDic o_ArgsDic; o_fFun.cMakeArgsDic(o_ArgsDic, a_Arg, a_Args...);
		return o_fFun.operator()(*this->c_pDic, o_ArgsDic);
	}
	else if (i_Type == tType::i_itClass)
	{
		return this->cCall("()", a_Arg, a_Args...);
	}

	throw exception(tStr::scCat("Type Error: Only <tRef -> tDic[tFun]> and <itClass> support \"()\"."));
}

tVar tVar::operator ()() 
{
	if (this->cType() == tType::i_itClass)
	{
		return this->cCall("()");
	}

	throw exception(tStr::scCat("Type Error: Only <tRef -> tDic[tFun]> and <itClass> support \"()\"."));
}

template<class a_tArg, class... a_tArgs>
tVar tVar::operator ()(a_tArg const& a_Arg, a_tArgs... a_Args) 
{ 
	if (this->cType() == tType::i_itClass)
	{
		return this->cCall("()", a_Arg, a_Args...);
	}

	throw exception(tStr::scCat("Type Error: Only <tRef -> tDic[tFun]> and <itClass> support \"()\"."));
}

template<class a_tWhich>
tVar operator ~(tRefVar<a_tWhich>& a_One)
{
	auto i_Type = a_One.cType();
	if (i_Type == tType::i_int) { return tVar(~a_One.operator long long()); }
	if (i_Type == tType::i_uint) { return tVar(~a_One.operator unsigned long long()); }
	if (i_Type == tType::i_itClass) { return tVar(a_One.eThis()->cVal().cTypedValAt<itClass>()->vdVoid_Op1("~_")); }
	throw exception(tStr::scCat("Arith Error: ~ <", a_One.cTypename(), ">"));
}

template<class a_tWhich>
tVar operator +(tRefVar<a_tWhich>& a_One)
{
	auto i_Type = a_One.cType();
	if (i_Type == tType::i_int || i_Type == tType::i_uint || i_Type == tType::i_float) { return tVar(a_One); }
	if (i_Type == tType::i_itClass) { return tVar(a_One.eThis()->cVal().cTypedValAt<itClass>()->vdVoid_Op1("+_")); }
	throw exception(tStr::scCat("Arith Error: + <", a_One.cTypename(), ">"));
}

template<class a_tWhich>
tVar operator -(tRefVar<a_tWhich>& a_One)
{
	auto i_Type = a_One.cType();
	if (i_Type == tType::i_int) { return tVar(-a_One.operator long long()); }
	if (i_Type == tType::i_float) { return tVar(-a_One.operator double()); }
	if (i_Type == tType::i_itClass) { return tVar(a_One.eThis()->cVal().cTypedValAt<itClass>()->vdVoid_Op1("-_")); }
	throw exception(tStr::scCat("Arith Error: - <", a_One.cTypename(), ">"));
}

inline tVar operator ~(tRef& a_One) { return operator ~<tRef>(a_One); }
inline tVar operator +(tRef& a_One) { return operator +<tRef>(a_One); }
inline tVar operator -(tRef& a_One) { return operator -<tRef>(a_One); }

inline tVar operator ~(tVar& a_One) { return operator ~<tVar>(a_One); }
inline tVar operator +(tVar& a_One) { return operator +<tVar>(a_One); }
inline tVar operator -(tVar& a_One) { return operator -<tVar>(a_One); }

tRef& tRef::operator =(ptVal const& a_pVal)
{
	this->c_pVal = (*a_pVal).vdCopy();
	if (this->c_pDic)
	{
		tDic::scSet(*this->c_pDic, this->c_DicKey, this->c_pVal);
	}
	else
	{
		tTup::scSet(*this->c_pTup, this->c_TupIdx, this->c_pVal);
	}
	return *this;
}

//tRef& tRef::operator =(tRefToTup const& a_RHS)
//{
//	return this->operator =(a_RHS.c_pVal);
//}

tRef& tRef::operator =(tVar const& a_RHS)
{
	return this->operator =(a_RHS.c_pVal);
}

tRef& tRef::operator =(tRefToTup const& a_RHS)
{
	return this->operator =(a_RHS.c_pVal);
}

tRef tRef::operator [](tStr a_Key)
{
	return this->operator tDic & ().operator[](a_Key);
}

tRefToTup tRef::operator [](int a_Idx)
{
	return this->operator tTup & ().operator[](a_Idx);
}

tRef tVar::operator [](tStr a_Key)
{
	return this->operator tDic&().operator[](a_Key);
}

tRefToTup tVar::operator [](int a_Idx)
{
	return this->operator tTup&().operator[](a_Idx);
}

template<class a_tVal>
tVar operator +(tRef const& a_LHS, a_tVal const& a_RHS) 
{ return (tVar(a_LHS) += a_RHS); }

template<class a_tVal>
tVar operator +(a_tVal const& a_LHS, tRef const& a_RHS) 
{ return (tVar(a_RHS) += a_LHS); }

template<class a_tVal>
tStr tValidVal<a_tVal>::vdToStr() const
{
	switch (this->i_Type)
	{
	case tType::i_null: return tStr("null");
	case tType::i_bool: return tStr(*this->cTypedValAt<bool>());
	case tType::i_int: return tStr(*this->cTypedValAt<long long>());
	case tType::i_uint: return tStr(*this->cTypedValAt<unsigned long long>());
	case tType::i_float: return tStr(*this->cTypedValAt<double>());
	case tType::i_tStr: return (*this->cTypedValAt<tStr>());
	case tType::i_tDic: return (*this->cTypedValAt<tDic>()).cToJson();
	case tType::i_tTup: return (*this->cTypedValAt<tTup>()).cToJson();
	}
	return tStr();
}

template<class a_tVal>
tStr tValidVal<a_tVal>::vdToJson(int a_Indent) const
{
	switch (this->i_Type)
	{
	case tType::i_null: return tStr("null");
	case tType::i_bool: return tStr(*this->cTypedValAt<bool>());
	case tType::i_int: return tStr(*this->cTypedValAt<long long>());
	case tType::i_uint: return tStr(*this->cTypedValAt<unsigned long long>());
	case tType::i_float: return tStr(*this->cTypedValAt<double>());
	case tType::i_tStr: return tStr::scCat('"', (*this->cTypedValAt<tStr>()).cEscape(), '"');
	case tType::i_tDic: return (*this->cTypedValAt<tDic>()).cToJson(a_Indent);
	case tType::i_tTup: return (*this->cTypedValAt<tTup>()).cToJson(a_Indent);
	}
	return tStr();
}

tTup tDic::cGet(tStr const& a_Key, tTup const& a_Dft) const
{
	return this->cHas(a_Key) ? (tTup const&)(*this->c_Map.at(a_Key)) : a_Dft;
}

tStr tDic::cToJson(int a_Indent) const
{
	tStr o_Rst('{');
	auto o_Keys = this->cKeys(true);
	if (!o_Keys)
	{
		o_Rst += '}';
		return o_Rst;
	}

	auto o_KL = o_Keys.cLen();
	for (int k = 0; k < o_KL; ++k)
	{
		o_Rst += "\n";
		o_Rst += tStr::scIndent(a_Indent + 4);
		o_Rst += '"';
		o_Rst += o_Keys[k].cEscape();
		o_Rst += "\": ";
		o_Rst += (*this)[o_Keys[k]].cToJson(a_Indent + 4);
		if (k < o_KL - 1) { o_Rst += ", "; }
	}
	o_Rst += "\n";
	o_Rst += tStr::scIndent(a_Indent);
	o_Rst += '}';
	return o_Rst;
}

tStr tTup::cToJson(int a_Indent) const
{
	auto o_AL = this->c_Ary.cLen();
	if (o_AL == 0)
	{
		return tStr("[]");
	}

	tStr o_Rst('[');
	for (int i = 0; i < o_AL; ++i)
	{
		o_Rst += "\n";
		o_Rst += tStr::scIndent(a_Indent + 4);
		o_Rst += (*this)[i].cToJson(a_Indent + 4);
		if (i < o_AL - 1) { o_Rst += ", "; }
	}
	o_Rst += "\n";
	o_Rst += tStr::scIndent(a_Indent);
	o_Rst += ']';
	return o_Rst;
}

template<class... a_tPs>
void tFun::tPrms::eAdd(tStr const& a_P, a_tPs... a_Ps)
{
	tTup::scAdd(this->c_Keys, a_P);
	tTup::scAdd(this->c_Dfts, i_Null);
	this->eAdd(a_Ps...);
}

template<class a_tVal, class... a_tPs>
void tFun::tPrms::eAdd(tKV<a_tVal> const& a_P, a_tPs... a_Ps)
{
	tTup::scAdd(this->c_Keys, a_P.c_Key);
	tTup::scAdd(this->c_Dfts, a_P.c_Val);
	this->eAdd(a_Ps...);
}

void tFun::cMakeArgsDic(tDic& a_Dic)
{
	// 现在a_Dic中含有全部实参，但可能缺少部分形参，补上默认值
	int o_KL = this->c_Prms.c_Keys.cLen();
	for (int i = 0; i < o_KL; ++i)
	{
		tStr o_Key = this->c_Prms.c_Keys[i];
		if (!a_Dic.cHas(o_Key))
		{
			a_Dic[o_Key] = this->c_Prms.c_Dfts[i];
		}
	}
}

bool operator ==(tDic const& a_LHS, tDic const& a_RHS)
{
	if (a_LHS.cLen() != a_RHS.cLen()) { return false; }

	for (auto o_Iter = a_LHS.c_Map.begin(); o_Iter != a_LHS.c_Map.end(); ++o_Iter)
	{
		if (!a_RHS.cHas(o_Iter->first) || (*a_LHS.c_Map.at(o_Iter->first) != *a_RHS.c_Map.at(o_Iter->first))) 
		{ return false; }
	}
	return true;
}

bool operator ==(tTup const& a_LHS, tTup const& a_RHS)
{
	if (a_LHS.cLen() != a_RHS.cLen()) { return false; }

	int o_Len = a_LHS.cLen();
	for (int i = 0; i < o_Len; ++i)
	{
		if ((*a_LHS.c_Ary[i] != *a_RHS.c_Ary[i]))
		{ return false; }
	}
	return true;
}


VOID_NS1(_nImp)

inline void fParseJson_SkipWS(tStr& a_Json)
{
	int o_Len = a_Json.cLen();
	for (int i = 0; i < o_Len; ++i)
	{
		if (!tStr::scIsWhiteSpace(a_Json[i]))
		{
			a_Json = a_Json.cSlice(i);
			return;
		}
	}
	a_Json.clear();
}

inline bool fParseJson_TryNullBool(bool& a_IsNull, bool& a_Bool, tStr& a_Json)
{
	a_IsNull = false;
	if ((a_Json[0] == 'n') && (a_Json.cSlice(0, 4) == "null"))  { a_IsNull = true; a_Json = a_Json.cSlice(4); return true; }
	if ((a_Json[0] == 'f') && (a_Json.cSlice(0, 5) == "false")) { a_Bool = false;  a_Json = a_Json.cSlice(5); return true; }
	if ((a_Json[0] == 't') && (a_Json.cSlice(0, 4) == "true"))  { a_Bool = true;   a_Json = a_Json.cSlice(4); return true; }
	return false;
}

inline bool fParseJson_Str(tStr& a_Errs, tStr& a_Rst, tStr& a_Json)
{
	int o_Len = a_Json.cLen(), o_Idx = 1; // [0]='"'
	int o_Esc = 0;
	while (o_Idx < o_Len)
	{
		char o_Now = a_Json[o_Idx];
		if (o_Esc == 0)
		{
			if (o_Now == '\\') { o_Esc = 1; ++o_Idx; }
			else if (o_Now == '"') { ++o_Idx; a_Json = a_Json.cSlice(o_Idx); return true; }
			else { a_Rst += o_Now; ++o_Idx; }
		}
		else
		{
			o_Esc = 0;
			if (o_Now == 't') { a_Rst += '\t'; ++o_Idx; }
			else if (o_Now == 'v') { a_Rst += '\v'; ++o_Idx; }
			else if (o_Now == 'f') { a_Rst += '\f'; ++o_Idx; }
			else if (o_Now == 'r') { a_Rst += '\r'; ++o_Idx; }
			else if (o_Now == 'n') { a_Rst += '\n'; ++o_Idx; }
			else if (o_Now == 'u') // \u????
			{
				if (o_Idx + 5 < o_Len) //[-1, +4]
				{
					a_Rst += a_Json.cSlice(o_Idx - 1, o_Idx + 5).cDecodeUnicodeEscape();
					o_Idx += 5;
				}
				else // 意外终止，放弃解析，按字面值处理
				{
					a_Rst += "\\u";
					++o_Idx;
				}
			}
			else // \\ \" ... 
			{
				a_Rst += o_Now;
				++o_Idx;
			}
		}
	}
	a_Errs = "Parsing <tStr> failed: Missing tail '\"'.";
	return false;
}

inline bool fParseJson_Num(tStr& a_Errs, double& a_Flt, long long& a_Int, unsigned long long& a_Uint, int& a_Which, tStr& a_Json)
{
	int o_Len = a_Json.cLen();
	bool o_Neg = false;
	int o_Idx = 0;
	if (a_Json[0] == '-') { o_Neg = true; ++o_Idx; }
	else if (a_Json[0] == '+') { ++o_Idx; }

	bool o_Dot = false;
	for (; o_Idx < o_Len; ++o_Idx)
	{
		if (a_Json[o_Idx] == '.') 
		{ 
			if (o_Dot) { a_Errs = "Parsing <int>/<float> failed: Multiple dots."; return false; } // 两个“.”
			o_Dot = true; 
		}
		else if ((a_Json[o_Idx] < '0') || ('9' < a_Json[o_Idx])) // 中止
		{
			break;
		}
	}

	tStr o_Src = a_Json.cSlice(0, o_Idx);
	if (o_Dot)
	{
		a_Which = 1;
		a_Flt = std::stod(o_Src);
	}
	else
	{
		try 
		{ 
			if (o_Neg)
			{
				a_Which = 2;
				a_Int = std::stoll(o_Src);
			}
			else
			{
				a_Which = 3;
				a_Uint = std::stoull(o_Src);
			}
		}
		catch (...) // 整数溢出时使用浮点数
		{ 
			a_Which = 1; 
			a_Flt = std::stod(a_Json.cSlice(0, o_Idx)); 
		} 
	}
	a_Json = a_Json.cSlice(o_Idx);
	return true;
}

inline bool fParseJson_Tup(tStr& a_Errs, tTup& a_Rst, tStr& a_Json);

inline bool fParseJson_Dic(tStr& a_Errs, tDic& a_Rst, tStr& a_Json)
{
	if (!a_Json) { return true; }

	a_Json = a_Json.cSlice(1); // {
	bool o_LastComma = false;
	while (a_Json)
	{
		fParseJson_SkipWS(a_Json);
		if (!a_Json) { a_Errs = "Parsing <tDic> failed: Missing tail \"}\"."; return false; }

		if (a_Json[0] == '}')
		{
			a_Json = a_Json.cSlice(1);
			return true;
		}

		if (a_Json[0] == ',')
		{
			if (o_LastComma) { a_Errs = "Parsing <tDic> failed: Consecutive commas."; return false; } // 连续逗号
			o_LastComma = true;
			a_Json = a_Json.cSlice(1);
			continue;
		}

		o_LastComma = false;

		if (a_Json[0] != '"')
		{
			a_Errs = "Parsing <tDic> failed: Key must be wrapped with '\"'.";
			return false;
		}

		tStr o_Key;
		if (!_nImp::fParseJson_Str(a_Errs, o_Key, a_Json)) // 字符串解析失败只有一种情况：没有包装进“"”
		{ a_Errs = "Parsing <tDic> failed: Key must be wrapped with '\"'."; return false; }
		
		fParseJson_SkipWS(a_Json);
		if (!a_Json || (a_Json[0] != ':'))
		{ a_Errs = "Parsing <tDic> failed: Missing \":\""; return false; }

		a_Json = a_Json.cSlice(1);
		fParseJson_SkipWS(a_Json);
		if (!a_Json) { a_Errs = "Parsing <tDic> failed: Missing value."; return false; }

		bool o_IsNull = false, o_Bool = false;
		if (fParseJson_TryNullBool(o_IsNull, o_Bool, a_Json))
		{
			if (o_IsNull) { tDic::scSet(a_Rst, o_Key, i_Null); }
			else { tDic::scSet(a_Rst, o_Key, o_Bool); }
			continue;
		}

		if ((a_Json[0] == '+') || (a_Json[0] == '-') || (('0' <= a_Json[0]) && (a_Json[0] <= '9')))
		{
			double o_Flt; long long o_Int; unsigned long long o_Uint; int o_Which;
			if (!_nImp::fParseJson_Num(a_Errs, o_Flt, o_Int, o_Uint, o_Which, a_Json)) { return false; }
			if (o_Which == 1) { tDic::scSet(a_Rst, o_Key, o_Flt); }
			else if (o_Which == 2) { tDic::scSet(a_Rst, o_Key, o_Int); }
			else { tDic::scSet(a_Rst, o_Key, o_Uint); }
		}
		else if (a_Json[0] == '"')
		{
			tStr o_Str;
			if (!_nImp::fParseJson_Str(a_Errs, o_Str, a_Json)) { return false; }
			tDic::scSet(a_Rst, o_Key, o_Str);
		}
		else if (a_Json[0] == '{')
		{
			tDic::scSet(a_Rst, o_Key, tDic());
			if (!fParseJson_Dic(a_Errs, (tDic&)a_Rst[o_Key], a_Json)) { return false; }
		}
		else if (a_Json[0] == '[')
		{
			tDic::scSet(a_Rst, o_Key, tTup());
			if (!fParseJson_Tup(a_Errs, (tTup&)a_Rst[o_Key], a_Json)) { return false; }
		}
		else
		{
			a_Errs = "Parsing <tDic> failed: Unexpected source \"";
			a_Errs += a_Json.cSlice(0, 10);
			a_Errs += "...\".";
			return false;
		}
	}
	return true;
}

bool fParseJson_Tup(tStr& a_Errs, tTup& a_Rst, tStr& a_Json)
{
	if (!a_Json) { return true; }

	a_Json = a_Json.cSlice(1); // [
	bool o_LastComma = false; 
	while (a_Json)
	{
		fParseJson_SkipWS(a_Json);
		if (!a_Json) { a_Errs = "Parsing <tTup> failed: Missing tail \"]\"."; return false; }

		if (a_Json[0] == ']')
		{
			a_Json = a_Json.cSlice(1);
			return true;
		}

		if (a_Json[0] == ',')
		{
			if (o_LastComma) { a_Errs = "Parsing <tTup> failed: Consecutive commas."; return false; } // 连续逗号
			o_LastComma = true;
			a_Json = a_Json.cSlice(1);
			continue;
		}

		o_LastComma = false;

		bool o_IsNull = false, o_Bool = false;
		if (fParseJson_TryNullBool(o_IsNull, o_Bool, a_Json))
		{
			if (o_IsNull) { a_Rst.cPushBack(i_Null); }
			else { a_Rst.cPushBack(o_Bool); }
			continue;
		}
		
		if ((a_Json[0] == '+') || (a_Json[0] == '-') || (('0' <= a_Json[0]) && (a_Json[0] <= '9')))
		{
			double o_Flt; long long o_Int; unsigned long long o_Uint; int o_Which;
			if (!_nImp::fParseJson_Num(a_Errs, o_Flt, o_Int, o_Uint, o_Which, a_Json)) { return false; }
			if (o_Which == 1) { a_Rst.cPushBack(o_Flt); }
			else if (o_Which == 2) { a_Rst.cPushBack(o_Int); }
			else { a_Rst.cPushBack(o_Uint); }
		}
		else if (a_Json[0] == '"')
		{
			tStr o_Str;
			if (!_nImp::fParseJson_Str(a_Errs, o_Str, a_Json)) { return false; }
			a_Rst.cPushBack(o_Str);
		}
		else if (a_Json[0] == '{')
		{
			a_Rst.cPushBack(tDic());
			if (!fParseJson_Dic(a_Errs, (tDic&)a_Rst.cBack(), a_Json)) { return false; }
		}
		else if (a_Json[0] == '[')
		{
			a_Rst.cPushBack(tTup());
			if (!fParseJson_Tup(a_Errs, (tTup&)a_Rst.cBack(), a_Json)) { return false; }
		}
		else 
		{
			a_Errs = "Parsing <tTup> failed: Unexpected source \"";
			a_Errs += a_Json.cSlice(0, 10);
			a_Errs += "...\".";
			return false;
		}
	}
	return false;
}

VOID_NS0(_nImp)

bool fParseJson(tStr& a_Errs, tVar& a_Rst, tStr a_Json)
{
	a_Errs.clear();
	a_Json = a_Json.cTrim();
	if (!a_Json) { a_Rst = i_Null; return true; }
	if (a_Json == "null") { a_Rst = i_Null; return true; }
	if (a_Json == "false") { a_Rst = false; return true; }
	if (a_Json == "true") { a_Rst = true; return true; }
	if ((a_Json[0] == '+') || (a_Json[0] == '-') || (('0' <= a_Json[0]) && (a_Json[0] <= '9')))
	{
		double o_Flt; long long o_Int; unsigned long long o_Uint; int o_Which;
		if (!_nImp::fParseJson_Num(a_Errs, o_Flt, o_Int, o_Uint, o_Which, a_Json)) { return false; }
		if (o_Which == 1) { a_Rst = o_Flt; return true; }
		else if (o_Which == 2) { a_Rst = o_Int; return true; }
		else { a_Rst = o_Uint; return true; }
	}
	if (a_Json[0] == '"') 
	{ 
		tStr o_Str;
		if (!_nImp::fParseJson_Str(a_Errs, o_Str, a_Json)) { return false; }
		a_Rst = o_Str;
		return true;
	}
	if (a_Json[0] == '{')
	{
		a_Rst = tDic();
		_nImp::fParseJson_Dic(a_Errs, (tDic&)a_Rst, a_Json);
		return true;
	}
	if (a_Json[0] == '[')
	{
		a_Rst = tTup();
		_nImp::fParseJson_Tup(a_Errs, (tTup&)a_Rst, a_Json);
		return true;
	}
	a_Errs = "Parsing json failed: Invalid source.";
	return false;
}

bool fParseJsonFromFile(tStr& a_Errs, tVar& a_Rst, tStr a_Path)
{
	ifstream o_F(a_Path);
	string o_Str((istreambuf_iterator<char>(o_F)), istreambuf_iterator<char>());
	return fParseJson(a_Errs, a_Rst, tStr(o_Str));
}


VOID_NS0(nVoid)




